/**
 * Copyright (c) 2009 Jim Hurne
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
package org.tzconverter.tzdisplay;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

import org.jdesktop.layout.GroupLayout;
import org.jdesktop.layout.LayoutStyle;
import org.tzconverter.gui.GradientButton;
import org.tzconverter.util.Icons;

/**
 * The view component of the TimeZoneDisplay triad.  The TimeZoneDisplay triad displays
 * the date/time in a particular time zone.  It also allows for converting the date/time
 * from one time zone into another.
 *
 * @since Apr 19, 2009
 */

public class TimeZoneDisplayPanel extends JPanel implements TimeZoneDisplayView
{
  private static final long serialVersionUID = 3657329939645546577L;

  private JLabel errorLabel;
  private JTextField timeZoneAbbrevLabel;
  private JTextField dateTimeField;
  private JButton convertButton;
  private JButton closeButton;
  
  private final Icons icons;

  public TimeZoneDisplayPanel(Icons icons) {
    this.icons = icons;
    
    this.setOpaque(false);
    
    createComponents();
    layoutComponents();
    
    this.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
    this.setMinimumSize(this.getPreferredSize());
  }

  private void createComponents()
  {
    errorLabel = new JLabel(" ");
    errorLabel.setIcon(icons.getError());
    errorLabel.setForeground(Color.RED);

    timeZoneAbbrevLabel = new JTextField(15);
    timeZoneAbbrevLabel.setOpaque(false);
    timeZoneAbbrevLabel.setMinimumSize(timeZoneAbbrevLabel.getPreferredSize());
    timeZoneAbbrevLabel.setBorder(BorderFactory.createEmptyBorder());
    timeZoneAbbrevLabel.setEditable(false);
    timeZoneAbbrevLabel.setFont(getFont().deriveFont(Font.BOLD));
    timeZoneAbbrevLabel.setForeground(Color.WHITE);

    convertButton = new GradientButton("Convert");
    convertButton.setIcon(icons.getCalc());

    closeButton = new JButton();
    closeButton.setBorder(null);
    closeButton.setContentAreaFilled(false);
    closeButton.setIcon(icons.getRemove());

    dateTimeField = new JTextField(17);
    Font dateTimeFont = dateTimeField.getFont().deriveFont(Font.BOLD);
    dateTimeField.setFont(dateTimeFont);
    dateTimeField.setMaximumSize(dateTimeField.getPreferredSize());

    dateTimeField.getDocument().addDocumentListener(new DocumentListener() {
      public void changedUpdate(DocumentEvent event)
      {
        //Do nothing
      }

      public void insertUpdate(DocumentEvent event)
      {
        Document doc = event.getDocument();
        try
        {
          firePropertyChange(PROP_DATE_TIME, null, doc.getText(0, doc.getLength()));
        }
        catch (BadLocationException e)
        {
          throw new RuntimeException(e.getMessage(), e);
        }
      }

      public void removeUpdate(DocumentEvent event)
      {
        Document doc = event.getDocument();
        try
        {
          firePropertyChange(PROP_DATE_TIME, null, doc.getText(0, doc.getLength()));
        }
        catch (BadLocationException e)
        {
          throw new RuntimeException(e.getMessage(), e);
        }
      }
    });
  }

  private void layoutComponents()
  {
    GroupLayout layout = new GroupLayout(this);
    this.setLayout(layout);

    layout.setAutocreateGaps(true);
    layout.setHonorsVisibility(true);

    layout.setHorizontalGroup(
        layout.createParallelGroup()
          .add(errorLabel)
          .add(
              layout.createSequentialGroup()
                .add(timeZoneAbbrevLabel)
                .add(dateTimeField)
                .add(convertButton)
                .add(closeButton)
                .addPreferredGap(LayoutStyle.RELATED, 5, 5)
              )
        );

    layout.setVerticalGroup(
        layout.createSequentialGroup()
          .add(errorLabel)
          .add(
              layout.createParallelGroup(GroupLayout.BASELINE)
                .add(timeZoneAbbrevLabel)
                .add(dateTimeField)
                .add(convertButton)
                .add(GroupLayout.CENTER, closeButton)
              )
        );
  }


  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#close()
   */
  public void close()
  {
    JComponent parent = (JComponent) this.getParent();
    parent.remove(this);
    parent.revalidate();
    parent.repaint();
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#showError(java.lang.String)
   */
  public void showError(String errorMessage)
  {
    errorLabel.setVisible(true);
    errorLabel.setText(errorMessage);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#clearError()
   */
  public void clearError()
  {
    errorLabel.setVisible(false);
    errorLabel.setText(" ");
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#isConvertEnabled()
   */
  public boolean isConvertEnabled()
  {
    return convertButton.isEnabled();
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#setConvertEnabled(boolean)
   */
  public void setConvertEnabled(boolean enabled)
  {
    convertButton.setEnabled(enabled);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#getDateTime()
   */
  public String getDateTime()
  {
    return dateTimeField.getText();
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#setDateTime(java.lang.String)
   */
  public void setDateTime(String date)
  {
    dateTimeField.setText(date);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#getTimeZoneAbbrev()
   */
  public String getTimeZoneName()
  {
    return timeZoneAbbrevLabel.getText();
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#setTimeZoneAbbrev(java.lang.String)
   */
  public void setTimeZoneName(String timeZoneAbbrev)
  {
    timeZoneAbbrevLabel.setText(timeZoneAbbrev);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#addActionListener(java.awt.event.ActionListener)
   */
  public void addConvertListener(ActionListener listener)
  {
    convertButton.addActionListener(listener);
  }

  /* (non-Javadoc)
   * @see org.tzconverter.tzdisplay.TimeZoneDisplayView#removeActionListener(java.awt.event.ActionListener)
   */
  public void removeConvertListener(ActionListener listener)
  {
    convertButton.removeActionListener(listener);
  }

  public void addCloseListener(ActionListener listener)
  {
    closeButton.addActionListener(listener);
  }

  public void removeCloseListener(ActionListener listener)
  {
    closeButton.removeActionListener(listener);
  }
}
